#ifndef IUVECTOR_H
#define IUVECTOR_H

#include <stdexcept>

template<typename T, unsigned int size>
class IUVectorBase
{
public:
	typedef IUVectorBase<T, size> ThisType;

	IUVectorBase() {
		for (int i = 0; i < size; i++)
		{
			scalar[i] = T();
		}
	}

	template<typename ...Arg>
	IUVectorBase(Arg ...arg):IUVectorBase(){
		static_assert(sizeof...(Arg) >= size,"Error Too ManyArguments");

		std::vector<T> vec {((T)arg)...};

		for (int i = 0;i<sizeof...(Arg);i++)
		{
			scalar[i] = vec[i];
		}
	}


	bool operator == (const IUVectorBase& other) const {
		for (int i = 0; i < size; i++)
		{
			if (other.scalar[i] != scalar[i])
			{
				return false;
			}
		}

		return true;
	}

	bool operator != (const IUVectorBase& o) const {
		return !(*this == o);
	}

	~IUVectorBase() {

	}

	template<typename T1>
	struct Iterator
	{
		T1 operator->() {
			return *p;
		}

		T1& operator*() {
			return *p;
		}

		void operator++() {
			p++;
		}

		void operator--() {
			p--;
		}

		bool operator ==(const Iterator& o) {
			return p == o.p;
		}

		bool operator != (const Iterator& o) {
			return p != o.p;
		}

	private:
		T1* p;
		friend class ThisType;
	};

	typedef Iterator<T> iterator;
	typedef Iterator<const T> const_iterator;

	iterator begin()
	{
		iterator it;
		it.p = scalar;
		return it;
	}

	iterator end() {
		iterator it;
		it.p = scalar + size;
		return it;
	}

	const_iterator begin() const
	{
		const_iterator it;
		it.p = scalar;
		return it;
	}

	const_iterator end() const {
		const_iterator it;
		it.p = scalar + size;
		return it;
	}

	const T& operator[](unsigned int index) const {
		if (index >= size) {
			throw std::out_of_range("Error index Out of Range");
		}

		return scalar[index];
	}

	T& operator[](unsigned int index) {
		if (index >= size) {
			throw std::out_of_range("Error index Out of Range");
		}

		return scalar[index];
	}
protected:
	T scalar[size];
};
#endif // !IUPOINT_H
